﻿#define  _CRT_SECURE_NO_WARNINGS 1

//操作符


//算数操作符  +-*/%

//int main()
//{
//	//int a = 7 / 2;
//	//int b = 7 % 2;//取模
//	//printf("%d\n", a);//3
//	//printf("%d\n", b);//1
//	//除号的两段都是整数的时候，执行的是整数除法，如果两段只要有一个浮点数就执行浮点数的除法
//	float a = 7 / 2.0;
//	int b = 7 % 2;//取模
//	//取模操作符的两端只能是整数
//	printf("%.2f\n", a);//3.50
//	printf("%d\n", b);//1
//
//	return 0;
//}


//移位操作符  >>   <<   (涉及2进制的运算，后面讲)

//位操作符   &  ^  |

//赋值操作符  =   +=   -=   *=   /=   &=   ^=    |=     >>=   <<=

//int main()
//{
//	int a = 0;//初始化
//	a = 20;//赋值
//
//	a = a + 3;//a=23
//	a += 3;
//
//	a -= 3;
//	a = a - 3;
//
//
//
//	return 0;
//}

//单目操作符

//a + b;
//  +  //双目操作符
//单目操作符 - 只有一个操作数的操作符

//!          逻辑反操作
//-          负值
//+          正值
//&          取地址
//sizeof     操作数的类型长度（以字节为单位）
//~          对一个数的二进制按位取反
//--         前置、后置--
//++         前置、后置++
//*          间接访问操作符(解引用操作符)
//(类型)     强制类型转换

//C语言中
//0表示假
//非0表示真

//int main()
//{
	/*int flag = 2;
	if (!flag)
	{
		printf("hehe\n");
	}*/

	/*int a = -10;
	int b = -a;
	printf("%d\n", b);*/

	//sizeof是操作符，是单目操作符

	//int a = 10;
	//printf("%d\n", sizeof(a));//4
	//printf("%d\n", sizeof(int));//4
	//printf("%d\n", sizeof a);//4

	//int arr[10] = { 0 };
	//printf("%d\n", sizeof(arr));//40,计算的是整个数组的大小，单位是字节
	//printf("%d\n", sizeof(arr[0]));//4
	//printf("%d\n", sizeof(arr) / sizeof(arr[0]));//10 - 数组的元素个数

//	return 0;
//}

//学习到操作符sizeof，明天继续，B站视频P17  24:18

#include <stdio.h>

//int main()
//{
//	//int a = 10;
//	
//	//int b = a++;//后置++，先使用，后++
//	// b = a; a = a+1;
//	//printf("%d\n", b);//10
//	//printf("%d\n", a);//11
//
//
//	//int b = ++a;//前置++，先++，后使用
//	//a=a+1;b=a;
//	//printf("%d\n", b);//11
//	//printf("%d\n", a);//11
//
//	//int a = 10;
//	//int b = a--;
//	////b=a;a=a-1;
//	//printf("%d\n", b);//10
//	//printf("%d\n", a);//9
//
//	//int a = 10;
//	//int b = --a;
//	////a=a-1;b=a;
//	//printf("%d\n", b);//9
//	//printf("%d\n", a);//9
//
//	//int a = (int)3.14;
//	//int a = int(3.14)//err
//	//printf("%d\n", a);
//	//3.14字面浮点数，编译器默认理解为double类型
//
//	return 0;
//}


//关系操作符
//>
//>=
//<
//<=
//!=     用于测试“不相等”
//==     用于测试“相等”


//逻辑操作符

//&&   逻辑与（并且）
//||   逻辑或（或者）

//int main()
//{
	/*int a = 0;
	int b = 20;
	if (a && b)
	{
		printf("hehe\n");
	}*/

	/*int a = 0;
	int b = 0;
	if (a || b)
	{
		printf("hehe\n");
	}*/

//	return 0;
//}

//条件操作符    （三目操作符）
//exp1 ? exp2 : exp3
// 真     1       0
// 假     0       1

//int main()
//{
//	//int a = 10;
//	//int b = 20;
//	//int r = a > b ? a : b;
//	//printf("%d\n", r);//20
//
//	//int a = 100;
//	//int b = 20;
//	//int r = a > b ? a : b;
//	//printf("%d\n", r);//100
//
//
//	return 0;
//}

//逗号表达式就是逗号隔开的一串表达式
//逗号表达式的特点是：从左向右依次计算，整个表达式的结果是最后一个表达式的结果

//int main()
//{
//	int a = 10;
//	int b = 20;
//	int c = 0;
//	         c=8         a=28      5
//	int d = (c = a - 2, a = b + c, c - 3);
//	printf("%d\n", d);//5
//
//	return 0;
//}

//下标引用、函数调用和结构成员
//[] () . ->

//int main()
//{
//	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
//	arr[3] = 20;//[]就是下表引用操作符，arr和3就是[]的操作数
//
//	return 0;
//}


//函数调用操作符()

//int Add(int x, int y)
//{
//	return x + y;
//}
//
//int main()
//{
//	int sum = Add(2, 3);//()就是函数调用操作符，Add,2,3都是()的操作数
//
//	return 0;
//}





//常见关键字 - C语言本身内置的，关键字不是自己创建出来的，也不能自己创建
//auto  break   case  char  const   continue  default  do   double else  enum
//extern float  for   goto  if   int   long  register    return   short  signed
//sizeof   static struct  switch  typedef union  unsigned   void  volatile  while

// for               if else            char        const 常属性        enum - 枚举
//while                                short                           struct - 结构体 
//do while            switch            int                            union - 联合体（共用体）
//break               case              long                           sizeof - 计算大小
//continue            default          float                           typedef - 类型重命名
//                                     double                          void - 无（函数的返回类型，函数参数）
//                     goto            signed - 有符号的
//                                    unsigned - 无符号的



//extern - 声明外部符号           register - 寄存器          return - 函数返回值
//                               static - 静态的

//变量的命名：
//1.有意义
//int age;
//float salary;
//2.名字必须是字母、数字、下划线组成
//不能有特殊字符，同时不能以数字开头。
//int 2b;//err
//int _2b;//ok
//3.变量名不能是关键字



//关键字typedef
//typedef 顾名思义是类型定义，这里应该理解为类型重命名。

//typedef unsigned int unit;
//
//typedef struct Node
//{
//	int date;
//	struct Node* next;
//}Node;
//
//int main()
//{
//	unsigned int num = 0;
//	unit num2 = 1;//简化
//	struct Node n;
//	Node n2;//简化
//
//	return 0;
//}



// 关键字static
//static是用来修饰变量和函数的
//1. 修饰局部变量 - 称为静态局部变量
//2. 修饰全局变量 - 称为静态全局变量
//3. 修饰函数 - 称为静态函数

//void test()
//{
//	static int a = 1;          //static修饰局部变量的时候，局部变量出了作用域，不销毁的。
//	a++;                       //本质上，static修饰局部变量的时候，改变了变量的存储位置。
//	printf("%d ", a);          //影响了变量的生命周期，生命周期变长，和程序的生命周期一样。
//}
//
//int main()
//{
//	int i = 0;
//	while (i < 10)
//	{
//		test();
//		i++;
//	}
//
//	return 0;
//}


//修饰全局变量

//extern int g_val;              //static修饰全局变量的时候，这个全局变量的外部链接属性就变成了内部链接属性
//                               //其他源文件（.c）就不能再使用到这个全局变量了。  
//int main()
//{
//	printf("%d\n", g_val);
//
//	return 0;
//}

//修饰函数

//extern int Add(int x, int y);      //函数也具有外部链接属性，但是被static修饰的时候，外部链接属性就变成了内部链接属性
//                                   //其他源文件(.c)就不能再使用了
//int main()
//{
//	int a = 10;
//	int b = 20;
//	int z = Add(a, b);
//	printf("%d\n", z);
//
//	return 0;
//}

//int main()
//{
//	//寄存器变量
//	register int num = 3;//建议3存放在寄存器中
//
//	return 0;
//}


//#define 定义常量和宏

#define NUM 100                //#define 定义标识符常量



#define ADD(x,y) ((x)+(y))     //#define定义宏
                               //宏是有参数的

//int main()
//{
//	/*printf("%d\n", NUM);
//	int n = NUM;
//	printf("%d\n", n);
//	int arr[NUM] = { 0 };*/
//
//	int a = 10;
//	int b = 20;
//	int c = ADD(a, b);
//	printf("%d\n", c);//30
//
//	return 0;
//}




//     指针
//1.内存
//内存是电脑上特别重要的存储器，计算机中程序的运行都是在内存中进行的 。
//所以为了有效的使用内存，就把内存划分成一个个小的内存单元，每个内存单元的大小是1个字节。
//为了能够有效的访问到内存的每个单元，就给内存单元进行了编号，这些编号被称为该内存单元的地址。



//int main()
//{
//	int a = 10;//向内存申请4个字节，存储10
//	//&a;//取地址操作符
//	//printf("%p\n", &a);//打印地址，%p是以地址的形式打印
//	int* p = &a;    //*说明p是指针变量   int说明p指向的对象是int类型的
//	//p就是指针变量
//	//内存单元
//	//编号 -> 地址 -> 地址也被称为指针
//	//存放指针（地址）的变量就是指针变量
//	*p = 20;//解引用操作符，意思就是通过p中存放的地址，找到p所指向的对象，*p就是p指向的对象
//	printf("%d\n", a);
//
//	/*char ch = 'w';
//	char* pc = &ch;*/
//
//	return 0;
//}


//2. 指针变量的大小

//指针变量的大小取决于地址的大小
//32位平台下地址是32个bit位（即4个字节）
//64位平台下地址是64个bit位（即8个字节）
//int main()
//{
//	printf("%zu\n", sizeof(char*));    //8
//	printf("%zu\n", sizeof(short*));   //8
//	printf("%zu\n", sizeof(int*));     //8
//	printf("%zu\n", sizeof(double*));  //8
//	printf("%zu\n", sizeof(float*));   //8
//
//	return 0;
//}



//   结构体   关键字：struct

//结构体是把一些单一类型组合在一起的做法。
//结构体是C语言中特别重要的知识点，结构体使得C语言有能力描述复杂类型。
//比如描述学生，学生包含： 名字 + 年龄 + 性别 + 学号 这几项信息。
//这里只能使用结构体来描述了。

//struct Stu
//{
//	//成员
//	char name[20];
//	int age;
//	char sex[10];
//	char tele[12];
//};
//
//void print(struct Stu* ps)
//{
//	printf("%s %d %s %s\n", (*ps).name, (*ps).age, (*ps).sex, (*ps).tele);
//	//->操作符
//	//结构体指针变量->成员名
//	printf("%s %d %s %s\n", ps->name, ps->age, ps->sex, ps->tele);
//}
//
//int main()
//{
//	struct Stu s = { "张三",20,"男","1546851318" };
//
//	//结构体对象.成员名
//	printf("%s %d %s %s\n", s.name, s.age, s.sex, s.tele);//.为结构成员访问操作符
//	print(&s);
//
//	return 0;
//}
